#Requires AutoHotkey v2.0

; a:=Format('"str:=inStr (str,\"\\\")?strReplace(str,\"\\\",\"\\V\\\\\"):strReplace(str,{1}\"\",{2}\\\"\")"',"'","'")
; str:='{"status": "hello", "results":[{"contents":"hello\"","trans":"你好"},{"contents":"world","trans":"世界"}]}'
; retMap:=JSON2.parse(str)
; msgBox type(retMap.results)
; for item in  retMap.results
;     msgBox item.contents "->" item.trans
class JSON2
{
    static uuidA:="0763C49802734108979739D89C0CC7A4" . A_NowUTC
    static uuidB:="C8C0655017FB428FB18EECF88E6E85CF" . A_NowUTC
    static uuidC:="08E3043B62324D0C8BDDB6A2A1DB4E6A" . A_NowUTC
    ;解析json
    static parse(str)
    {
        str:=inStr(str,'\\')?strReplace(str,'\\',this.uuidC):str ;替换 \\
        str:=inStr(str,'\"')?strReplace(str,'\"',this.uuidA):str ;替换 \"
        str:=inStr(str,"'")?strReplace(str,"'",this.uuidB):str   ;替换 '
        return this.recurve(str)
    }
    ;Func 把对象转换为字符串
    static stringify(obj)
    {
        return  this.GetJS().JSON.stringify(obj)
    }
    ;递归解析json
    static recurve(str,recFlag:=0)
    {
        static eval := ObjBindMethod(this.GetJS(), 'eval')
        if not recFlag{
            obj:= eval(Format('(function(){obj=JSON.parse({1}{2}{3});!(obj.length)&&(obj["keys"]=Object.keys(obj));return obj})()'
            ,"'",str,"'"))
            return this.recurve(obj,1)
        }
        if(type(str)=="ComObject"){
           if(str.hasOwnProperty("length")){ ;数组
               tmpArr:=[]
               Loop str.length {
                 if type(value:=str.%A_index-1%)=="ComObject"
                    tmpArr.push(this.recurve(this.recurve(this.stringify(value),0),1))
                 else
                    tmpArr.push(this.recurve(value,1))
               }
               return tmpArr
           }else{  ;对象 注意js的下标是0开始
               tmpObject:={}
               Loop str.keys.length{
                  key:=str.keys.%A_index-1%
                  if type(value:=str.%key%)=="ComObject"{
                     tmpObject.%key%:=this.recurve(this.recurve(this.stringify(value),0),1)
                  }else
                    tmpObject.%key%:=this.recurve(value,1) ;
               }
               return tmpObject
           }
        }else{ ;普通类型,可能是已经组装好的map或者是组装好的array
;            msgBox type(str)
           if type(str)=="Object" or type(str)=="Array"
                return str
           str:=inStr(str,this.uuidA)?strReplace(str,this.uuidA,'"'):str
           str:=inStr(str,this.uuidB)?strReplace(str,this.uuidB,"'"):str
           str:=inStr(str,this.uuidC)?strReplace(str,this.uuidC,"\"):str
           return str
        }
    }
    ;获取JS对象
    static GetJS() {
        static document := '', JS
        if !document {
            document := ComObject('HTMLFILE')
            document.write('<meta http-equiv="X-UA-Compatible" content="IE=9">')
            JS := document.parentWindow
            (document.documentMode < 9 && JS.execScript())
        }
        return JS
    }
}